package com.aaa.marketresearch.webclient.gwt.admin.widget;

import com.aaa.marketresearch.webclient.gwt.admin.AdminRequester;
import com.aaa.marketresearch.webclient.gwt.domain.Family;
import com.aaa.marketresearch.webclient.gwt.domain.FamilyMember;
import com.aaa.marketresearch.webclient.gwt.domain.Goods;
import com.aaa.marketresearch.webclient.gwt.util.ConsoleLog;
import com.aaa.marketresearch.webclient.gwt.util.Responder;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;


import java.util.ArrayList;
import java.util.List;

/**
 * @author Nail
 */
public class FamilyTable extends Composite {
    interface FamilyTableUiBinder extends UiBinder<Widget, FamilyTable> {
    }

    private static FamilyTableUiBinder uiBinder = GWT.create(FamilyTableUiBinder.class);

    private static FamilyTable instance = null;

    public static FamilyTable getInstance() {
        if (instance == null) {
            instance = new FamilyTable();
        }
        return instance;
    }

    @UiField
    Button addFamily;

    @UiField
    FlowPanel familyTable;

    @UiField
    FlowPanel familyMembersTable;

    @UiField
    Button saveFamily;

    @UiField
    Button addFamilyMember;

    @UiField
    TextBox familyName;

    @UiField
    TextBox familyPassword;

    @UiField
    TextBox familyEmail;

    @UiField
    ListBox familyRole;

    @UiField
    VerticalPanel familyMemberPanel;

    private CellTable table;

    private List<Family> familyData;

    //private List<FamilyMemberCell> familyMember = new ArrayList<FamilyMemberCell>();

    private Family selectedFamily;

    public FamilyTable() {
        // initialize
        initWidget(uiBinder.createAndBindUi(this));

        table = new CellTable();

        table.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.ENABLED);

        // Add a text column to show the name.
        TextColumn<Family> nameColumn = new TextColumn<Family>() {
            @Override
            public String getValue(Family object) {
                return object.getName();
            }
        };
        table.addColumn(nameColumn, "Name");

        // Add a text column to show the email.
        TextColumn<Family> emailColumn = new TextColumn<Family>() {
            @Override
            public String getValue(Family object) {
                return object.getEmail();
            }
        };
        table.addColumn(emailColumn, "Email");

        // Add a text column to show the role.
        TextColumn<Family> roleColumn = new TextColumn<Family>() {
            @Override
            public String getValue(Family object) {
                return object.getRole();
            }
        };
        table.addColumn(roleColumn, "Role");

        // Add a selection model to handle user selection.
        final SingleSelectionModel<Family> selectionModel = new SingleSelectionModel<Family>();
        table.setSelectionModel(selectionModel);
        selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
            public void onSelectionChange(SelectionChangeEvent event) {
                Family selected = selectionModel.getSelectedObject();
                if (selected != null) {
                    FamilyTable.this.setActiveFamily(selected);
                }
            }
        });

        this.familyTable.add(table);

        this.saveFamily.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                FamilyTable.this.saveFamily();
            }
        });

        this.addFamilyMember.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                FamilyTable.this.addNewMember();
            }
        });

        this.addFamily.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                FamilyTable.this.addNewFamily();
            }
        });

    }

    public void loadData() {
        AdminRequester request = new AdminRequester();
        request.addResponder(new Responder() {
            @Override
            public void handleGetResponse(String content) {
                FamilyTable.this.familiesUpdated(content);
            }
        });
        request.getAllFamily();
    }

    private void familiesUpdated(String content) {
        JSONArray data = (JSONArray) JSONParser.parseLenient(content);
        int n = data.size();

        this.familyData = new ArrayList<Family>(n);

        for (int i = 0; i < n; i++) {
            JSONObject obj = data.get(i).isObject();
            Family family = new Family(obj);
            this.familyData.add(family);
        }

        table.setRowCount(this.familyData.size(), true);
        table.setRowData(0, this.familyData);
    }

    private void setActiveFamily(Family family) {
        this.selectedFamily = family;
        this.familyName.setText(family.getName());
        this.familyPassword.setText(family.getPassword());
        this.familyEmail.setText(family.getEmail());
        int n = this.familyRole.getItemCount();
        for (int i = 0; i < n; i++) {
            String value = this.familyRole.getValue(i);
            if (value.equalsIgnoreCase(family.getRole())) {
                this.familyRole.setSelectedIndex(i);
                break;
            }
        }
        familyMemberPanel.clear();

        if (family.getId() != null) {
            AdminRequester request = new AdminRequester();
            request.addResponder(new Responder() {
                @Override
                public void handleGetResponse(String content) {
                    FamilyTable.this.familyMembersUpdated(content);
                }
            });
            request.getFamilyMembers(family.getId());
        }
    }

    private void familyMembersUpdated(String content) {
        JSONArray data = (JSONArray) JSONParser.parseLenient(content);
        int n = data.size();
        for (int i = 0; i < n; i++) {
            JSONObject obj = data.get(i).isObject();
            FamilyMember familyMember = new FamilyMember(obj);
            FamilyMemberCell familyMemberCell = new FamilyMemberCell();
            familyMemberCell.setFamilyMember(familyMember);
            this.familyMemberPanel.add(familyMemberCell);
        }
    }


    private void saveFamily() {
        if (this.selectedFamily != null) {
            this.selectedFamily.setName(this.familyName.getText());
            this.selectedFamily.setPassword(this.familyPassword.getText());
            this.selectedFamily.setEmail(this.familyEmail.getText());
            this.selectedFamily.setRole(this.familyRole.getValue(this.familyRole.getSelectedIndex()));
            AdminRequester familyRequest = new AdminRequester();

            familyRequest.addResponder(new Responder() {
                @Override
                public void handleGetResponse(String content) {
                    ConsoleLog.getInstance().info("saved family");
                    if (content!= null && content.length() > 0) {
                        Integer id = Integer.parseInt(content);
                        saveFamilyMembers(id);
                    }
                }
            });
            familyRequest.saveFamily(this.selectedFamily);
        }
    }

    private void saveFamilyMembers(Integer familyId) {
        int n = this.familyMemberPanel.getWidgetCount();
        if (n > 0) {
            ConsoleLog.getInstance().info("familyMembers");
            JSONArray data = new JSONArray();
            for (int i = 0; i < n; i++) {
                FamilyMemberCell familyMemberCell = (FamilyMemberCell) this.familyMemberPanel.getWidget(i);
                FamilyMember familyMember = familyMemberCell.getFamilyMember();
                familyMember.setFamilyId(familyId);
                data.set(i, familyMember.getJSON());
            }
            AdminRequester familyMemberRequest = new AdminRequester();
            familyMemberRequest.addResponder(new Responder() {
                @Override
                public void handleGetResponse(String content) {
                    ConsoleLog.getInstance().info("saved familyMembers");
                    loadData();
                }
            });
            familyMemberRequest.saveFamilyMembers(data);
        }
    }


    private void addNewMember() {
        FamilyMember familyMember = new FamilyMember();
        familyMember.setFamilyId(this.selectedFamily.getId());
        FamilyMemberCell familyMemberCell = new FamilyMemberCell();
        familyMemberCell.setFamilyMember(familyMember);
        this.familyMemberPanel.add(familyMemberCell);
    }

    private void addNewFamily() {
        Family family = new Family();
        this.familyData.add(0, family);

        table.setRowCount(this.familyData.size(), true);
        table.setRowData(0, this.familyData);
    }

}
